﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace VoxelCollision
{
    public class Grid
    {
        public float size = 1;
        public int x;
        public int y;
        public int z;
        public BitArray[,] bitArrays;
        private int startX = 0;
        private int startY = 0;
        private int startZ = 0;


        public void initialize(int x, int y, int z, float size = 1f)
        {
            this.size = size;
            this.x = x;
            this.y = y;
            this.z = z;
            bitArrays = new BitArray[y, z];
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < z; j++)
                {
                    BitArray array = new BitArray(x);
                    for (int k = 0; k < x; k++)
                    {
                        array[k] = false;
                    }
                    bitArrays[i, j] = array;
                }
            }
        }

        public void Set(int x, int y, int z, bool val)
        {
            bitArrays[y, z][x] = val;
        }


        public bool isCollision(Vector3 pos, Vector3 size)
        {
            //计算BOX的8个顶点  所在的格子
            initPoints(pos, size);
            //查找格子是否是阻挡     
            for (int i = 0; i < 8; i++)
            {
                int rx = points[i, 0];
                int ry = points[i, 1];
                int rz = points[i, 2];
                if (bitArrays[ry, rz][rx])
                {
                    return true;
                }
            }
            return false;
        }

        int[,] points = new int[8, 3];
        public void initPoints(Vector3 pos, Vector3 size)
        {
            for (int i = 0; i < 8; i++)
            {
                //8个点
                int y = i % 2 == 0 ? 1 : -1;
                int z = i <= 3 ? 1 : -1;
                int x = i <= 1 || i >= 6 ? 1 : -1;
                points[i, 0] = Mathf.FloorToInt((pos.x + size.x * 0.5f * x - startX) / this.size);
                points[i, 1] = Mathf.FloorToInt((pos.y + size.y * 0.5f * y - startY) / this.size);
                points[i, 2] = Mathf.FloorToInt((pos.z + size.z * 0.5f * z - startZ) / this.size);
            }
        }

        private bool isInRed(int x, int y, int z, Vector3 pos, Vector3 size)
        {
            int rx = Mathf.FloorToInt((pos.x + size.x * 0.5f * x - startX) / this.size);
            int ry = Mathf.FloorToInt((pos.y + size.y * 0.5f * y - startY) / this.size);
            int rz = Mathf.FloorToInt((pos.z + size.z * 0.5f * z - startZ) / this.size);
            //Vector3 resultPos = new Vector3(pos.x + size.x * 0.5f * x, pos.y + size.y * 0.5f * y, pos.z + size.z * 0.5f * z);
            //initXYZ(resultPos);
            return bitArrays[ry, rz][rx];
        }
        private void initXYZ(Vector3 pos)
        {
            int rx = Mathf.FloorToInt((pos.x - startX) / size);
            int ry = Mathf.FloorToInt((pos.y - startY) / size);
            int rz = Mathf.FloorToInt((pos.z - startZ) / size);
        }

        public void draw()
        {
            Vector3 cubeSize = new Vector3(size, size, size);
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < z; j++)
                {
                    BitArray array = bitArrays[i, j];
                    for (int k = 0; k < array.Length; k++)
                    {
                        if (array[k])
                        {
                            Vector3 center = new Vector3(startX + k * size + size * 0.5f, startY + i * size + size * 0.5f, startZ + j * size + size * 0.5f);
                            //Gizmos.color = array[k] ? Color.red : Color.green;
                            Gizmos.color = Color.red;
                            Gizmos.DrawWireCube(center, cubeSize);
                        }
                    }
                }
            }

            //for (int i = 0; i < y; i++)
            //{
            //    for (int j = 0; j < z; j++)
            //    {
            //        BitArray array = bitArrays[i, j];
            //        for (int k = 0; k < array.Length; k++)
            //        {
            //            Vector3 center = new Vector3(startX + k * size + size * 0.5f, startY + i * size + size * 0.5f, startZ + j * size + size * 0.5f);
            //            Gizmos.color = array[k] ? Color.red : Color.green;
            //            Gizmos.DrawWireCube(center, cubeSize);
            //        }
            //    }
            //}
        }


    }


}

